﻿// Decompiled with JetBrains decompiler
// Type: NetickEditor.NetworkConfigEditor
// Assembly: Netick.Unity.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 0658BB4A-05C4-428D-9BD6-82E94959F5A1
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Editor\Netick.Unity.Editor.dll

using Netick;
using Netick.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

#nullable disable
namespace NetickEditor;

[CustomEditor(typeof (NetickConfig))]
[CanEditMultipleObjects]
public class NetworkConfigEditor : Editor
{
  private SerializedProperty Prefabs;
  private SerializedProperty AutoGetPrefabs;
  private SerializedProperty PrefabsPath;
  private SerializedProperty TickRate;
  private SerializedProperty MaxPlayers;
  private SerializedProperty MaxObjects;
  private SerializedProperty ServerDivisor;
  private SerializedProperty CallNetworkRender;
  private SerializedProperty CallNetworkUpdate;
  private SerializedProperty NetworkRenderInvokeOrder;
  private SerializedProperty LagCompEnable;
  private SerializedProperty PhysicsPrediction;
  private SerializedProperty PhysicsType;
  private SerializedProperty EnableLogging;
  private SerializedProperty EnableProfiling;
  private SerializedProperty InterestManagement;
  private SerializedProperty NarrowphaseFiltering;
  private SerializedProperty InterestGroupCount;
  private SerializedProperty WorldSize;
  private SerializedProperty AoILayerCount;
  private SerializedProperty CellSize0;
  private SerializedProperty CellSize1;
  private SerializedProperty CellSize2;
  private SerializedProperty CellSize3;
  private SerializedProperty CellSize4;
  private SerializedProperty RenderWorldGrid;
  private SerializedProperty RenderedLayer;
  private SerializedProperty SyncTransformOnSpawn;
  private SerializedProperty MaxAdditiveScenes;
  private SerializedProperty DuplicateInputOnLowFPS;
  private SerializedProperty MaxSendableDataSize;
  private SerializedProperty MemoryAllocatorStateBlockSizeSize;
  private SerializedProperty MemoryAllocatorMetaBlockSizeSize;
  private SerializedProperty AggressivePreAllocation;
  private SerializedProperty FastSerialization;
  private SerializedProperty IncludeInactiveObjects;
  private SerializedProperty EnableMultithreading;
  private SerializedProperty AccurateLocalSnapshots;
  private SerializedProperty MaxAllowedTimestep;
  private SerializedProperty ExtraInterpolationDelay;
  private SerializedProperty MaxPredicatedTicks;
  private NetickConfig Config;
  private static int SelectedTab;
  private bool IsP;
  private Dictionary<System.Type, int> SortedScriptToOrder;
  private List<ScriptOrderListItem> SortedScriptToOrder_;
  internal static float TickPeriod;

  internal bool IsValid => this.serializedObject.targetObject != (UnityEngine.Object) null;

  private void OnEnable()
  {
    if (this.serializedObject == null)
      return;
    this.Prefabs = this.serializedObject.FindProperty("Prefabs");
    this.AutoGetPrefabs = this.serializedObject.FindProperty("AutoGetPrefabs");
    this.PrefabsPath = this.serializedObject.FindProperty("PrefabsPath");
    this.TickRate = this.serializedObject.FindProperty("TickRate");
    this.MaxAllowedTimestep = this.serializedObject.FindProperty("MaxAllowedTimestep");
    this.ExtraInterpolationDelay = this.serializedObject.FindProperty("ExtraInterpolationDelay");
    this.AccurateLocalSnapshots = this.serializedObject.FindProperty("AccurateLocalInterpolation");
    this.EnableLogging = this.serializedObject.FindProperty("EnableLogging");
    this.EnableProfiling = this.serializedObject.FindProperty("EnableProfiling");
    this.EnableMultithreading = this.serializedObject.FindProperty("EnableMultithreading");
    this.MaxPlayers = this.serializedObject.FindProperty("MaxPlayers");
    this.MaxObjects = this.serializedObject.FindProperty("MaxObjects");
    this.MaxPredicatedTicks = this.serializedObject.FindProperty("MaxPredictedTicks");
    this.MaxAdditiveScenes = this.serializedObject.FindProperty("MaxAdditiveScenes");
    this.ServerDivisor = this.serializedObject.FindProperty("ServerDivisor");
    this.PhysicsPrediction = this.serializedObject.FindProperty("PhysicsPrediction");
    this.PhysicsType = this.serializedObject.FindProperty("PhysicsType");
    this.CallNetworkRender = this.serializedObject.FindProperty("InvokeRenderInHeadless");
    this.CallNetworkUpdate = this.serializedObject.FindProperty("InvokeUpdate");
    this.NetworkRenderInvokeOrder = this.serializedObject.FindProperty("RenderInvokeOrder");
    this.MaxSendableDataSize = this.serializedObject.FindProperty("MaxSendableDataSize");
    this.DuplicateInputOnLowFPS = this.serializedObject.FindProperty("InputReuseAtLowFPS");
    this.MemoryAllocatorStateBlockSizeSize = this.serializedObject.FindProperty("StateAllocatorBlockSize");
    this.MemoryAllocatorMetaBlockSizeSize = this.serializedObject.FindProperty("MetaAllocatorBlockSize");
    this.AggressivePreAllocation = this.serializedObject.FindProperty("AggressivePreAllocation");
    this.FastSerialization = this.serializedObject.FindProperty("FastSerialization");
    this.IncludeInactiveObjects = this.serializedObject.FindProperty("IncludeInactiveObjects");
    this.SyncTransformOnSpawn = this.serializedObject.FindProperty("SyncTransformOnSpawn");
    this.InterestManagement = this.serializedObject.FindProperty("EnableInterestManagement");
    this.NarrowphaseFiltering = this.serializedObject.FindProperty("EnableNarrowphaseFiltering");
    this.InterestGroupCount = this.serializedObject.FindProperty("CustomGroupCount");
    this.AoILayerCount = this.serializedObject.FindProperty("AoILayerCount");
    this.CellSize0 = this.serializedObject.FindProperty("AoILayer0CellSize");
    this.CellSize1 = this.serializedObject.FindProperty("AoILayer1CellSize");
    this.CellSize2 = this.serializedObject.FindProperty("AoILayer2CellSize");
    this.CellSize3 = this.serializedObject.FindProperty("AoILayer3CellSize");
    this.CellSize4 = this.serializedObject.FindProperty("AoILayer4CellSize");
    this.WorldSize = this.serializedObject.FindProperty("WorldSize");
    this.RenderWorldGrid = this.serializedObject.FindProperty("RenderWorldGrid");
    this.RenderedLayer = this.serializedObject.FindProperty("RenderedLayer");
    this.LagCompEnable = this.serializedObject.FindProperty("EnableLagCompensation");
    this.IsP = NetworkConfigEditor.IsAssemblyLoaded("Netick.Pro");
  }

  public virtual void OnInspectorGUI()
  {
    if (this.serializedObject.targetObject == (UnityEngine.Object) null)
    {
      this.Repaint();
    }
    else
    {
      UnityEngine.Object targetObject = this.serializedObject.targetObject;
      if ((UnityEngine.Object) this.Config == (UnityEngine.Object) null)
        this.Config = (NetickConfig) this.serializedObject.targetObject;
      string str = "\n\nNote: update != packet. Because a single update could be one or more packets, depending on how much data needs to be sent.";
      new GUIStyle(GUI.skin.label).alignment = TextAnchor.MiddleCenter;
      bool flag = this.Config.Prefabs != null && this.Config.Prefabs.Count > 0;
      this.serializedObject.Update();
      EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth / 3f;
      NetickEditorToggleState.ShowGeneralSettings = EditorGUILayout.BeginFoldoutHeaderGroup(NetickEditorToggleState.ShowGeneralSettings, "General", (GUIStyle) null, (Action<Rect>) null, (GUIStyle) null);
      if (NetickEditorToggleState.ShowGeneralSettings)
      {
        EditorGUI.BeginDisabledGroup(Application.isPlaying);
        NetickEditorProperty.DrawProperty(targetObject, this.TickRate);
        NetworkConfigEditor.TickPeriod = 1f / this.TickRate.floatValue;
        string helpText = $"Server send rate: {1f / NetworkConfigEditor.TickPeriod / (float) this.ServerDivisor.intValue} updates per second. \n\nThis is how many updates per second will be sent from the server to every connected client. A higher rate results in higher bandwidth usage.{str}";
        NetickEditorProperty.DrawSendRateSlider(targetObject, this.ServerDivisor, "Server Send Rate", helpText);
        NetickEditorProperty.DrawProperty(targetObject, this.MaxPlayers);
        this.MaxPlayers.intValue = Math.Min(2048 /*0x0800*/, this.MaxPlayers.intValue);
        NetickEditorProperty.DrawProperty(targetObject, this.MaxObjects);
        NetickEditorProperty.DrawProperty(targetObject, this.PhysicsPrediction);
        NetickEditorProperty.DrawProperty(targetObject, this.PhysicsType);
        NetickEditorProperty.DrawProperty(targetObject, this.CallNetworkUpdate);
        NetickEditorProperty.DrawProperty(targetObject, this.CallNetworkRender);
        NetickEditorProperty.DrawProperty(targetObject, this.NetworkRenderInvokeOrder);
        EditorGUI.EndDisabledGroup();
        NetickEditorProperty.DrawProperty(targetObject, this.EnableLogging);
        EditorGUI.BeginDisabledGroup(Application.isPlaying);
        NetickEditorProperty.DrawProperty(targetObject, this.EnableProfiling);
        EditorGUI.EndDisabledGroup();
      }
      EditorGUILayout.EndFoldoutHeaderGroup();
      if (this.IsP)
      {
        EditorGUILayout.Space(3f);
        NetickEditorToggleState.ShowIM = EditorGUILayout.BeginFoldoutHeaderGroup(NetickEditorToggleState.ShowIM, "Interest Management", (GUIStyle) null, (Action<Rect>) null, (GUIStyle) null);
        if (NetickEditorToggleState.ShowIM)
        {
          Color color = GUI.color;
          EditorGUI.BeginDisabledGroup(!this.IsP);
          if (this.IsP)
          {
            EditorGUI.BeginDisabledGroup(Application.isPlaying);
            NetickEditorProperty.DrawProperty(targetObject, "Enable", this.InterestManagement);
            EditorGUI.BeginDisabledGroup(!this.InterestManagement.boolValue);
            NetickEditorProperty.DrawProperty(targetObject, "Narrow Phase Filtering", this.NarrowphaseFiltering);
            NetickEditorProperty.DrawProperty(targetObject, this.InterestGroupCount);
            NetickEditorProperty.DrawProperty(targetObject, this.WorldSize, "Size of the game world. Used for Area of Interest.");
            NetickEditorProperty.DrawProperty(targetObject, "AOI Layer Count", this.AoILayerCount);
            NetickEditorProperty.DrawProperty(targetObject, "AOI Layer 0 Cell Size", this.CellSize0, "Size of Area of Interest Layer 0 cells.");
            if (this.AoILayerCount.intValue > 1)
              NetickEditorProperty.DrawProperty(targetObject, "AOI Layer 1 Cell Size", this.CellSize1, "Size of Area of Interest Layer 1 cells.");
            if (this.AoILayerCount.intValue > 2)
              NetickEditorProperty.DrawProperty(targetObject, "AOI Layer 2 Cell Size", this.CellSize2, "Size of Area of Interest Layer 2 cells.");
            if (this.AoILayerCount.intValue > 3)
              NetickEditorProperty.DrawProperty(targetObject, "AOI Layer 3 Cell Size", this.CellSize3, "Size of Area of Interest Layer 3 cells.");
            if (this.AoILayerCount.intValue > 4)
              NetickEditorProperty.DrawProperty(targetObject, "AOI Layer 4 Cell Size", this.CellSize4, "Size of Area of Interest Layer 4 cells.");
            NetickEditorProperty.DrawProperty(targetObject, this.RenderWorldGrid, "Enable this to render the world grid and the Area of Interest of the client.");
            if (this.RenderWorldGrid.boolValue)
              NetickEditorProperty.DrawProperty(targetObject, this.RenderedLayer, "Choose which layer will be visualized in the server.");
            EditorGUI.EndDisabledGroup();
          }
          EditorGUI.EndDisabledGroup();
        }
        EditorGUILayout.EndFoldoutHeaderGroup();
        EditorGUILayout.Space(3f);
        NetickEditorToggleState.ShowLagCompSettings = EditorGUILayout.BeginFoldoutHeaderGroup(NetickEditorToggleState.ShowLagCompSettings, "Lag Compensation", (GUIStyle) null, (Action<Rect>) null, (GUIStyle) null);
        if (NetickEditorToggleState.ShowLagCompSettings)
        {
          EditorGUI.BeginDisabledGroup(Application.isPlaying);
          NetickEditorProperty.DrawProperty(targetObject, "Enable ", this.LagCompEnable);
          EditorGUI.EndDisabledGroup();
        }
        EditorGUILayout.EndFoldoutHeaderGroup();
      }
      EditorGUILayout.Space(3f);
      NetickEditorToggleState.ShowAdvancedSettings = EditorGUILayout.BeginFoldoutHeaderGroup(NetickEditorToggleState.ShowAdvancedSettings, "Advanced", (GUIStyle) null, (Action<Rect>) null, (GUIStyle) null);
      if (NetickEditorToggleState.ShowAdvancedSettings)
      {
        EditorGUI.BeginDisabledGroup(Application.isPlaying);
        NetickEditorProperty.DrawProperty(targetObject, this.MaxAdditiveScenes);
        NetickEditorProperty.DrawProperty(targetObject, this.SyncTransformOnSpawn);
        NetickEditorProperty.DrawProperty(targetObject, this.MaxSendableDataSize);
        NetickEditorProperty.DrawProperty(targetObject, this.MemoryAllocatorStateBlockSizeSize);
        NetickEditorProperty.DrawProperty(targetObject, this.MemoryAllocatorMetaBlockSizeSize);
        EditorGUI.BeginDisabledGroup(this.NarrowphaseFiltering.boolValue && this.InterestManagement.boolValue);
        NetickEditorProperty.DrawProperty(targetObject, this.FastSerialization);
        EditorGUI.EndDisabledGroup();
        NetickEditorProperty.DrawProperty(targetObject, this.EnableMultithreading);
        NetickEditorProperty.DrawProperty(targetObject, this.AggressivePreAllocation);
        NetickEditorProperty.DrawProperty(targetObject, this.ExtraInterpolationDelay);
        NetickEditorProperty.DrawProperty(targetObject, this.AccurateLocalSnapshots);
        NetickEditorProperty.DrawProperty(targetObject, this.MaxAllowedTimestep);
        NetickEditorProperty.DrawProperty(targetObject, this.MaxPredicatedTicks);
        NetickEditorProperty.DrawProperty(targetObject, this.DuplicateInputOnLowFPS);
        NetickEditorProperty.DrawProperty(targetObject, this.IncludeInactiveObjects);
        EditorGUI.EndDisabledGroup();
      }
      EditorGUILayout.EndFoldoutHeaderGroup();
      EditorGUILayout.Space(3f);
      NetickEditorToggleState.ShowMiscSettings = EditorGUILayout.BeginFoldoutHeaderGroup(NetickEditorToggleState.ShowMiscSettings, "Misc", (GUIStyle) null, (Action<Rect>) null, (GUIStyle) null);
      if (NetickEditorToggleState.ShowMiscSettings)
      {
        int selectedTab = NetworkConfigEditor.SelectedTab;
        NetworkConfigEditor.SelectedTab = GUILayout.Toolbar(NetworkConfigEditor.SelectedTab, new string[2]
        {
          "Prefabs",
          "Script Order"
        });
        EditorGUILayout.EndFoldoutHeaderGroup();
        if (selectedTab != NetworkConfigEditor.SelectedTab)
          NetickEditorToggleState.SelectedPropertyName = "";
        EditorGUILayout.Space(2f);
        GUIStyle style = GUI.skin.GetStyle("HelpBox");
        style.richText = true;
        style.margin.bottom = 5;
        style.border.top = 15;
        style.border.bottom = 15;
        style.border.left = 15;
        style.border.right = 15;
        style.fontSize = 12;
        style.padding = new RectOffset(10, 10, 10, 10);
        if (NetworkConfigEditor.SelectedTab == 0)
        {
          NetickEditorProperty.DrawLabel(targetObject, "What is this?", "", "These are the global network prefabs of your game. Which you can instantiate on the server using NetworkSandbox.NetworkInstantiate.\r\n\r\nIf you don't see your prefab here, make sure you've added NetworkObject component to it.");
          EditorGUI.BeginDisabledGroup(Application.isPlaying);
          NetickEditorProperty.DrawProperty(targetObject, this.AutoGetPrefabs);
          if (this.Config.AutoGetPrefabs)
          {
            NetickEditorProperty.DrawProperty(targetObject, "Path", this.PrefabsPath, "Path where Netick will fetch network prefabs from.");
            if (GUILayout.Button("Regenerate"))
              NetickPrefabTools.LoadAllNetworkedPrefabs(this.Config);
          }
          EditorGUI.BeginDisabledGroup(this.Config.AutoGetPrefabs);
          EditorGUILayout.PropertyField(this.Prefabs, Array.Empty<GUILayoutOption>());
          EditorGUI.EndDisabledGroup();
          if (!flag)
            EditorGUILayout.HelpBox("No network prefabs in the prefabs list.", (MessageType) 1);
          EditorGUI.EndDisabledGroup();
        }
        else
        {
          if (this.SortedScriptToOrder == null)
          {
            this.SortedScriptToOrder_ = new List<ScriptOrderListItem>(100);
            this.SortedScriptToOrder = ExecutionOrderSystem.ProcessAndGetOrders(NetickUtils.GetAllSubclassOf(typeof (NetickBehaviour)));
            foreach (KeyValuePair<System.Type, int> keyValuePair in this.SortedScriptToOrder)
              this.SortedScriptToOrder_.Add(new ScriptOrderListItem()
              {
                Name = keyValuePair.Key.Name,
                Order = keyValuePair.Value
              });
            this.SortedScriptToOrder_ = this.SortedScriptToOrder_.OrderBy<ScriptOrderListItem, int>((Func<ScriptOrderListItem, int>) (x => x.Order)).ToList<ScriptOrderListItem>();
          }
          NetickEditorProperty.DrawLabel(targetObject, "What is this?", "", "Use the Script Execution Order System to specify the relative order that Netick invokes the event functions (such as NetworkStart, NetworkUpdate, NetworkFixedUpdate, etc.) of different NetworkBehaviour/NetickBehaviour classes. For example, you can specify that Netick should run the event functions of your MovementController NetworkBehaviour script before it runs those of your WeaponController NetworkBehaviour script.\r\n\r\nTo specify the order of execution of your scripts, you use the attributes [ExecuteBefore], [ExecuteAfter], and [ExecutionOrder]\r\n\r\nFor example, to run MovementController script before WeaponController, you add the [ExecuteBefore] attribute to the definition of MovementController:\r\n\r\n[ExecuteBefore(typeof(WeaponController))]\r\nPublic class MovementController : NetworkBehaviour\r\n.....\r\n");
          EditorGUILayout.LabelField("Execution order is from top to bottom:", style, Array.Empty<GUILayoutOption>());
          foreach (ScriptOrderListItem scriptOrderListItem in this.SortedScriptToOrder_)
            this.DrawScriptOrderElement(scriptOrderListItem.Name, scriptOrderListItem.Order.ToString());
        }
      }
      this.serializedObject.ApplyModifiedProperties();
    }
  }

  private void DrawScriptOrderElement(string name, string order)
  {
    string str = "cs Script Icon";
    if (name == "NetworkSceneManager")
      return;
    if (name == "NetworkTransform")
      str = "sv_icon_dot2_pix16_gizmo";
    if (name == "NetworkRigidbody")
      str = "sv_icon_dot2_pix16_gizmo";
    if (name == "NetworkRigidbody2D")
      str = "sv_icon_dot2_pix16_gizmo";
    if (name == "NetworkAnimator")
      str = "sv_icon_dot2_pix16_gizmo";
    if (name == "PhysicsSimulationStep")
      str = "sv_icon_dot2_pix16_gizmo";
    if (name == "LagCompensationStep")
      str = "sv_icon_dot2_pix16_gizmo";
    if (name == "NetworkSceneManager")
      name = "SceneManager";
    EditorGUILayout.LabelField(new GUIContent(" " + name, EditorGUIUtility.IconContent(str).image), new GUIContent(order), new GUILayoutOption[1]
    {
      GUILayout.ExpandWidth(true)
    });
  }

  public static void HorizontalLine(Color color, float height, Vector2 margin)
  {
    GUILayout.Space(margin.x);
    EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, height, Array.Empty<GUILayoutOption>()), color);
    GUILayout.Space(margin.y);
  }

  internal static bool IsAssemblyLoaded(string name)
  {
    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
      if (assembly.FullName.Contains(name))
        return true;
    }
    return false;
  }
}
